﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Logging;
using VAdvantage.Utility;
using VAdvantage.Classes;
using System.Windows.Printing;
using System.Threading;
using System.Windows.Media.Imaging;

namespace VAdvantage.Print
{
    public class View : Canvas
    {
        /**	Layout to be Printed		*/
        private LayoutEngine m_layout;


        /**	Zoom Level						*/
        private int m_zoomLevel = 0;
        /** Zoom Options					*/
        public static String[] ZOOM_OPTIONS = new String[] { "100%", "75%", "50%" };
        /**	Margin around paper				*/
        public static int MARGIN = 5;
        /** Margin Background Color			*/
        private static Color COLOR_BACKGROUND = Colors.LightGray;

        /**	Logger			*/
        private static VLogger log = VLogger.GetVLogger(typeof(View).FullName);

        public View(LayoutEngine layout)
        {
            m_layout = layout;
        }

        /// <summary>
        /// Minimum Size
        /// </summary>
        /// <returns>Max Page Size</returns>
        public Size GetMinimumSize()
        {
            return GetMaximumSize();
        }	//	getMinimumSize


        /// <summary>
        /// Maximize Size
        /// </summary>
        /// <returns>Max Page Size</returns>
        public Size GetMaximumSize()
        {
            return new Size(GetPaperWidth() + (2 * MARGIN),
                (GetPaperHeight() + MARGIN) * GetPageCount() + MARGIN);
        }	//	getMaximumSize


        /// <summary>
        /// Preferred Size
        /// </summary>
        /// <returns>Max Page Size</returns>
        public Size GetPreferredSize()
        {
            return GetMaximumSize();
        }	//	getPreferredSize


        /// <summary>
        /// Set Zoom Level
        /// </summary>
        /// <param name="level"></param>
        public void SetZoomLevel(int level)
        {
            m_zoomLevel = level;
        }	//	setZoomLevel

        /// <summary>
        /// Set Zoom Level
        /// </summary>
        /// <param name="levelString">zoom level string</param>
        public void SetZoomLevel(String levelString)
        {
            for (int i = 0; i < ZOOM_OPTIONS.Length; i++)
            {
                if (ZOOM_OPTIONS[i].Equals(levelString))
                {
                    m_zoomLevel = i;
                    break;
                }
            }
        }	//	setZoomLevel


        /// <summary>
        /// Get Zoom Level
        /// </summary>
        /// <returns>Zoom Level in Int</returns>
        public int GetZoomLevel()
        {
            return m_zoomLevel;
        }	//	getZoomLevel

        /// <summary>
        /// Get Rectange of Page
        /// </summary>
        /// <param name="pageNo">page no</param>
        /// <returns>rectangle</returns>
        public Rectangle GetRectangleOfPage(int pageNo)
        {
            int y = MARGIN + ((GetPaperHeight() + MARGIN) * (pageNo - 1));
            Rectangle rect = new Rectangle();
            rect.Margin = new Thickness(MARGIN, y, 0, 0);
            rect.Height = GetPaperHeight();
            rect.Width = GetPaperWidth();
            return rect;
        }	//	getRectangleOfPage

        /// <summary>
        /// Get Page at Point
        /// </summary>
        /// <param name="p">Point</param>
        /// <returns>page as float to determine also position on page</returns>
        public double GetPageNoAt(Point p)
        {
            double y = p.Y;
            double pageHeight = GetPaperHeight() + MARGIN;
            return 1f + (y / pageHeight);
        }	//	getPageAt

        /// <summary>
        /// Counts the Pages
        /// </summary>
        /// <returns>Number of Pages in int</returns>
        public int GetPageCount()
        {
            return m_layout.GetPages().Count;
        }	//	getPageCount

        /// <summary>
        /// Get Page Info for Multi-Page tables
        /// </summary>
        /// <param name="pageNo">page</param>
        /// <returns>info e.g. (1,1)</returns>
        public String GetPageInfo(int pageNo)
        {
            return m_layout.GetPageInfo(pageNo);
        }	//	getPageInfo

        public String GetPageInfoMax()
        {
            return m_layout.GetPageInfoMax();
        }	//	getPageInfo

        public CPaper GetPaper()
        {
            return m_layout.GetPaper();
        }	//	getPaper

        public int GetPaperHeight()
        {
            //return 0;
            return (int)m_layout.GetPaper().GetHeight(true);
        }	//	getPaperHeight

        public int GetPaperWidth()
        {
            //return 0;
            return (int)m_layout.GetPaper().GetWidth(true);
        }	//	getPaperHeight

        public void RefreshMe()
        {
            this.UpdateLayout();
        }

        Viewer mViewer = null;

        public void Paint(Viewer viewer)
        {
            mViewer = viewer;
            bool b = System.Windows.Deployment.Current.Dispatcher.CheckAccess();

            if (b)
            {

                Rectangle bounds = new Rectangle();
                bounds.Width = 800;
                bounds.Width = 700;
                bounds.Margin = new Thickness(0, 0, 0, 0);
                bounds.Fill = new SolidColorBrush(Colors.LightGray);
                this.Children.Add(bounds);

                for (int page = 0; page < m_layout.GetPages().Count; page++)
                {
                    Rectangle pageRectangle = GetRectangleOfPage(page + 1);
                    this.Height = (pageRectangle.Height * m_layout.GetPages().Count) + 50;
                    Page p = (Page)m_layout.GetPages()[page];
                    p.Paint(this, pageRectangle, true, false);		//	sets context
                    m_layout.GetHeaderFooter().Paint(this, pageRectangle, true);

                    //break;
                }

                
            }
            else
            {
                bool pass = false;
                Dispatcher.BeginInvoke(delegate
                {
                    this.Children.Clear();
                    Rectangle bounds = new Rectangle();
                    bounds.Width = 800;
                    bounds.Width = 700;
                    bounds.Margin = new Thickness(0, 0, 0, 0);
                    bounds.Fill = new SolidColorBrush(Colors.LightGray);
                    this.Children.Add(bounds);

                    for (int page = 0; page < m_layout.GetPages().Count; page++)
                    {
                        Rectangle pageRectangle = GetRectangleOfPage(page + 1);
                        this.Height = (pageRectangle.Height * m_layout.GetPages().Count) + 50;
                        Page p = (Page)m_layout.GetPages()[page];
                        p.Paint(this, pageRectangle, true, false);		//	sets context
                        m_layout.GetHeaderFooter().Paint(this, pageRectangle, true);

                        //break;
                    }

                    mViewer.SetBusy(false);
                    pass = true;
                });

                while (!pass)
                    Thread.Sleep(20);

                pass = false;
            }
        }


        PrintDocument doc = new PrintDocument();

        public void Print()
        {
            doc.EndPrint += new EventHandler<EndPrintEventArgs>(doc_EndPrint);
            doc.PrintPage += new EventHandler<PrintPageEventArgs>(doc_PrintPage);
            doc.BeginPrint += new EventHandler<BeginPrintEventArgs>(doc_BeginPrint);
            
            doc.Print("report");
        }

        void doc_BeginPrint(object sender, BeginPrintEventArgs e)
        {
            m_PageNum = 0;
        }


        int m_PageNum = 0;
        void doc_PrintPage(object sender, PrintPageEventArgs e)
        {
            try
            {
                //Rectangle pageRectangle = GetRectangleOfPage(m_PageNum + 1);

                //WriteableBitmap bitmap = new WriteableBitmap((int)pageRectangle.Width, (int)pageRectangle.Height);
                //ScaleTransform transform = new ScaleTransform();
                //transform.ScaleX = pageRectangle.Margin.Left;
                //transform.ScaleY = pageRectangle.Margin.Top;
                //bitmap.Render(this, transform);
                //bitmap.Invalidate();

                //Viewbox printview = new Viewbox();
                //printview.Height = (int)pageRectangle.Height;
                //printview.Width = (int)pageRectangle.Width;
                //printview.Child = this;
                e.PageVisual = this;
                ++m_PageNum;
                e.HasMorePages = (m_PageNum < m_layout.GetPages().Count);
                    
            }
            catch
            {
            }
        }


        void doc_EndPrint(object sender, EndPrintEventArgs e)
        {
            m_PageNum = 0;
        }

    }
}
